package org.leumasjaffe.security;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Formatter;

public class HashFunctionTest {
    private static SecureRandom random = new SecureRandom();
    private static String pool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    private static int poolSize = 62;

    public static String calculateFileHash(MessageDigest algorithm, String fileName) throws Exception{

    	try (FileInputStream     fis = new FileInputStream(fileName);
    			BufferedInputStream bis = new BufferedInputStream(fis);
    			DigestInputStream   dis = new DigestInputStream(bis, algorithm)) {

    		// read the file and update the hash calculation
    		while (dis.read() != -1);

    		// get the hash value as byte array
    		byte[] hash = algorithm.digest();
    		return byteArray2Hex(hash);
        }
    }
    
    public static String calculateStringHash(MessageDigest algorithm, String data) throws Exception{

        InputStream is = new ByteArrayInputStream(data.getBytes());
        BufferedInputStream bis = new BufferedInputStream(is);
        DigestInputStream   dis = new DigestInputStream(bis, algorithm);

        // read the file and update the hash calculation
        while (dis.read() != -1);

        // get the hash value as byte array
        byte[] hash = algorithm.digest();

        return byteArray2Hex(hash);
    }
    
    public static String calculateSaltedHash(MessageDigest algorithm, String data, int size)
    throws Exception {
    	String salt = randomString(size);
    	return calculateSaltedHash(algorithm, data, salt);
    }
    
    public static String calculateSaltedHash(MessageDigest algorithm, String data, String salt)
    throws Exception {
    	return salt + calculateStringHash(algorithm, salt + data);
    }
    
    private static String randomString(int size) {
    	char[] buffer = new char[size];
    	for (int i = 0; i < size; i++) {
    		buffer[i] = pool.charAt(random.nextInt(poolSize));
    	}
		return new String(buffer);
	}

	private static String byteArray2Hex(byte[] hash) {
		try (Formatter formatter = new Formatter()) {
			for (byte b : hash) {
				formatter.format("%02x", b);
			}
			String ret = formatter.toString();
			return ret;
		}
    }

//    public static void main(String[] args) throws Exception {
//        String fileName = "javablogging.png";
//
//        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
//        MessageDigest md5  = MessageDigest.getInstance("MD5");        
//
//        System.out.println(calculateStringHash(md5, fileName));
//        System.out.println(calculateSaltedHash(md5, fileName, 16)); 
//        System.out.println();
//        System.out.println(calculateStringHash(sha1, fileName));
//        System.out.println(calculateSaltedHash(sha1, fileName, 16));        
//    }
}